package com.test.restruant.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.test.restruant.alipay.AlipayConfig;
import com.test.restruant.pojo.DishOrder;
import com.test.restruant.service.DishOrderService;
import com.test.restruant.wxpay.HttpUtil;
import com.test.restruant.wxpay.WXPayUtil;
import com.test.restruant.wxpay.ZxingUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * @author 徒有琴
 */
@Controller
public class OrderController {
    @Reference
    private DishOrderService dishOrderService;

    @RequestMapping("orderList")
    @ResponseBody
    public List<DishOrder> list() {
        return dishOrderService.getOrderList();
    }

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("order.html")
    public void order(String orderNum, HttpServletResponse response) {
        DishOrder dishOrder = dishOrderService.getOrderByOrderNum(orderNum);
        // 商户订单号，商户网站订单系统中唯一订单号，必填
        String out_trade_no = orderNum;
        // 订单名称，必填
        String subject = "ali test";
        System.out.println(subject);
        // 付款金额，必填
        String total_amount = dishOrder.getAmount().toString();
        // 销售产品码 必填
        String product_code = "QUICK_WAP_WAY";
        /**********************/
        // SDK 公共请求类，包含公共请求参数，以及封装了签名与验签，开发者无需关注签名与验签
        //调用RSA签名方式
        AlipayClient client = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGNTYPE);
        AlipayTradeWapPayRequest alipay_request = new AlipayTradeWapPayRequest();

        // 封装请求支付信息
        AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
        model.setOutTradeNo(out_trade_no);
        model.setSubject(subject);
        model.setTotalAmount(total_amount);
        //model.setBody(body);
        // model.setTimeoutExpress(timeout_express);
        model.setProductCode(product_code);
        alipay_request.setBizModel(model);
        // 设置异步通知地址
        alipay_request.setNotifyUrl(AlipayConfig.notify_url);
        // 设置同步地址
        alipay_request.setReturnUrl(AlipayConfig.return_url);

        // form表单生产
        String form = "";
        try {
            // 调用SDK生成表单
            form = client.pageExecute(alipay_request).getBody();
            response.setContentType("text/html;charset=" + AlipayConfig.CHARSET);
            response.getWriter().write(form);//直接将完整的表单html输出到页面
            response.getWriter().flush();
            response.getWriter().close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
//    @RequestMapping("order.html")
//    public String order(String orderNum, Model model) {
//        DishOrder order = dishOrderService.getOrderByOrderNum(orderNum);
//        //判断订单是否已经支付成功，如果已经支付，那就不支付了  略
//
//        model.addAttribute("order", order);
//        return "order";
//    }

    @RequestMapping("code")
    public void code(String orderNum, HttpServletRequest request, HttpServletResponse response) throws Exception {
        DishOrder order = dishOrderService.getOrderByOrderNum(orderNum);
        Map<String, String> param = new HashMap<>();
        param.put("appid", "wx632c8f211f8122c6");
        param.put("mch_id", "1497984412");
        param.put("nonce_str", WXPayUtil.generateNonceStr());
        param.put("body", "JSAPI支付测试");
        param.put("out_trade_no", order.getOrderNum());
        param.put("total_fee", order.getAmount().toString());
        param.put("spbill_create_ip", request.getRemoteAddr());
        param.put("notify_url", "http://2361k301i0.iok.la/callback");
        param.put("trade_type", "NATIVE ");
        try {
            String xml = WXPayUtil.generateSignedXml(param, "sbNCm1JnevqI36LrEaxFwcaT0hkGxFnC");
            System.out.println(xml);
            //String result = restTemplate.postForObject("https://api.mch.weixin.qq.com/pay/unifiedorder", new String(xml.getBytes("iso-8859-1"),"utf-8"), String.class);
            String result = HttpUtil.doPost("https://api.mch.weixin.qq.com/pay/unifiedorder", xml);
            System.out.println(new String(result.getBytes("iso-8859-1"), "utf-8"));
            Map<String, String> resultMap = WXPayUtil.xmlToMap(result);
            String codeUrl = resultMap.get("code_url");
            BufferedImage image = ZxingUtil.createImage(codeUrl, 300, 300);
            ImageIO.write(image, "JPEG", response.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    String success = "\n" +
            "\n" +
            "<xml>\n" +
            "\n" +
            "  <return_code><![CDATA[SUCCESS]]></return_code>\n" +
            "  <return_msg><![CDATA[OK]]></return_msg>\n" +
            "</xml>\n";
    String fail = "\n" +
            "\n" +
            "<xml>\n" +
            "\n" +
            "  <return_code><![CDATA[ERROR]]></return_code>\n" +
            "  <return_msg><![CDATA[ERROR]]></return_msg>\n" +
            "</xml>\n";

    @RequestMapping("callback.html")
    public void callali(HttpServletRequest request, HttpServletResponse response) throws Exception {
        PrintWriter out = response.getWriter();
//获取支付宝POST过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
            params.put(name, valueStr);
        }
        //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
        //商户订单号
        System.out.println(params);
        String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
        //支付宝交易号
        DishOrder dishOrder = dishOrderService.getOrderByOrderNum(out_trade_no);//查询本地订单
        String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");

        //交易状态
        String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");

        //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
        //计算得出通知验证结果
        //boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
        boolean verify_result = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, "RSA2");

        if (verify_result) {//验证成功
            //////////////////////////////////////////////////////////////////////////////////////////
            //请在这里加上商户的业务逻辑程序代码

            //——请根据您的业务逻辑来编写程序（以下代码仅作参考）——

            if (trade_status.equals("TRADE_FINISHED")) {
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
                //如果有做过处理，不执行商户的业务程序

                //注意：
                //如果签约的是可退款协议，退款日期超过可退款期限后（如三个月可退款），支付宝系统发送该交易状态通知
                //如果没有签约可退款协议，那么付款完成后，支付宝系统发送该交易状态通知。
            } else if (trade_status.equals("TRADE_SUCCESS")) {
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
                //如果有做过处理，不执行商户的业务程序
                //注意：
                //如果签约的是可退款协议，那么付款完成后，支付宝系统发送该交易状态通知。
                //更新订单等操作，同微信

            }

            //——请根据您的业务逻辑来编写程序（以上代码仅作参考）——
            out.println("success");    //请不要修改或删除

            //////////////////////////////////////////////////////////////////////////////////////////
        } else {//验证失败
            out.println("fail");
        }
    }

    @RequestMapping("callback")
    public void callback(HttpServletRequest request, HttpServletResponse response) {
        InputStream inputStream = null;
        StringBuilder builder = new StringBuilder();
        BufferedReader reader = null;
        String line = null;
        try {
            inputStream = request.getInputStream();
            reader = new BufferedReader(new InputStreamReader(inputStream));
            while ((line = reader.readLine()) != null) {
                builder.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                reader.close();
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try {
            String result = builder.toString();
            System.out.println(result);
            Map<String, String> map = WXPayUtil.xmlToMap(result);
            //验证签名
            boolean checkSign = WXPayUtil.isSignatureValid(result, "sbNCm1JnevqI36LrEaxFwcaT0hkGxFnC");
            if (checkSign) {
                String orderNum = map.get("out_trade_no");
                DishOrder order = dishOrderService.getOrderByOrderNum(orderNum);
                if (order.getStatus() == 1) {//如果已经支付成功了，则不需要处理
                    response.getWriter().write(success);
                    return;
                } else {//订单没支付成功，则更新订单状态
                    //验证支付金额是否正确
                    Integer cash = Integer.parseInt(map.get("cash_fee"));
                    if (cash.intValue() == order.getAmount().intValue()) {//收到的钱和订单的钱一样，正确
                        order.setStatus(1);//支付成功
                        order.setTradeNum(map.get("transaction_id"));//支付平台订单号
                        order.setResult(result);
                        dishOrderService.update(order);
                        response.getWriter().write(success);
                        return;
                    }
                }
            } else {
                response.getWriter().write(fail);
                return;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
